package com.slipper.sfts.member.service;

import java.math.BigDecimal;
import java.util.List;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

import com.slipper.common.util.BeanUtil;
import com.slipper.common.util.StringUtil;
import com.slipper.sfts.api.member.bo.MemberBrokerAccountHistoryBO;
import com.slipper.sfts.member.dao.MemberBrokerAccountHistoryDao;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import com.slipper.sfts.member.dao.MemberBrokerAccountDao;
import com.slipper.sfts.api.member.bo.MemberBrokerAccountBO;

import com.slipper.common.transaction.ReadTransactional;
import com.slipper.common.transaction.WriteTransactional;
import com.slipper.common.util.Tool;

@Service
@ReadTransactional
public class MemberBrokerAccountService {
    @Resource
    private MemberBrokerAccountDao memberBrokerAccountDao;
    @Resource
    private MemberBrokerAccountHistoryDao memberBrokerAccountHistoryDao;
    
    public MemberBrokerAccountBO queryBy(String id) {
        return memberBrokerAccountDao.queryBy(id);
    }

    public MemberBrokerAccountBO queryOneBy(String memberId, String brokerAccountId) {
        return memberBrokerAccountDao.queryOneBy(memberId, brokerAccountId);
    }

    public List<MemberBrokerAccountBO> queryList(MemberBrokerAccountBO bo) {
        return memberBrokerAccountDao.queryList(bo);
    }
    
    public PageInfo<MemberBrokerAccountBO> queryPage(MemberBrokerAccountBO bo) {
        PageHelper.startPage(bo.getPageNumber(), bo.getPageSize());
        return new PageInfo<>(memberBrokerAccountDao.queryList(bo));
    }
    
    @WriteTransactional
    public int save(MemberBrokerAccountBO bo) {
        int result;
        if (bo.getId() != null && !"".equals(bo.getId())) {
            result = memberBrokerAccountDao.update(bo);
        } else {
            bo.setId(Tool.getUUID());
            result = memberBrokerAccountDao.insert(bo);
        }
        this.saveHistory(bo, null, null);
        return result;
    }

    @WriteTransactional
    public int save(String memberId, List<MemberBrokerAccountBO> list, String employeeId) {
        if (StringUtil.isBlank(memberId)) {
            return 0;
        }

        for (MemberBrokerAccountBO account : list) {
            account.setMemberId(memberId);
            if (StringUtil.isBlank(account.getId())) {
                account.setId(Tool.getUUID());
                account.setUpdateId(employeeId);
                account.setCreateId(employeeId);
                memberBrokerAccountDao.insert(account);
            } else {
                account.setUpdateId(employeeId);
                memberBrokerAccountDao.update(account);
            }
            this.saveHistory(account, null, null);
        }

        // 删除被删除的数据
        MemberBrokerAccountBO qo = new MemberBrokerAccountBO();
        qo.setMemberId(memberId);
        memberBrokerAccountDao.queryList(qo).forEach(account -> {
            if (list.stream().noneMatch(temp -> account.getId().equals(temp.getId()))) {
                memberBrokerAccountDao.delete(account);
            }
        });

        return 1;
    }
    
    @WriteTransactional
    public int delete(MemberBrokerAccountBO bo) {
        return memberBrokerAccountDao.delete(bo);
    }

    public List<MemberBrokerAccountBO> queryListByMemberId(String memberId) {
        return memberBrokerAccountDao.queryListByMemberId(memberId);
    }

    @WriteTransactional
    public void saveHistory(MemberBrokerAccountBO bo, BigDecimal changeFreezeMoney, BigDecimal changeAvailableMoney) {
        MemberBrokerAccountHistoryBO history = BeanUtil.copy(bo, MemberBrokerAccountHistoryBO.class);
        history.setId(Tool.getUUID());
        history.setAccountId(bo.getId());
        history.setChangeFreezeMoney(changeFreezeMoney);
        history.setChangeAvailableMoney(changeAvailableMoney);
        memberBrokerAccountHistoryDao.insert(history);
    }

    @WriteTransactional
    public void freezeMoney(String memberId, String brokerAccountId, BigDecimal freezeMoney) {
        MemberBrokerAccountBO memberBrokerAccount = memberBrokerAccountDao.lockBy(memberId, brokerAccountId);
        if (memberBrokerAccount == null) return;

        // 增加冻结金额
        if (memberBrokerAccount.getFreezeMoney() == null) {
            memberBrokerAccount.setFreezeMoney(new BigDecimal(0));
        }
        memberBrokerAccount.setFreezeMoney(memberBrokerAccount.getFreezeMoney().add(freezeMoney));

        // 减少可用金额
        if (memberBrokerAccount.getAvailableMoney() == null) {
            memberBrokerAccount.setAvailableMoney(new BigDecimal(0));
        }
        BigDecimal availableMoney = memberBrokerAccount.getAvailableMoney().subtract(freezeMoney);
        memberBrokerAccount.setAvailableMoney(availableMoney);
        memberBrokerAccountDao.update(memberBrokerAccount);

        this.saveHistory(memberBrokerAccount, freezeMoney, null);
    }

    @WriteTransactional
    public void unfreezeMoney(String memberId, String brokerAccountId, BigDecimal unfreezeMoney) {
        if (unfreezeMoney == null || unfreezeMoney.compareTo(new BigDecimal(0)) == 0) return;

        MemberBrokerAccountBO memberBrokerAccount = memberBrokerAccountDao.lockBy(memberId, brokerAccountId);
        if (memberBrokerAccount == null) return;

        // 减少冻结金额
        if (memberBrokerAccount.getFreezeMoney() == null) {
            memberBrokerAccount.setFreezeMoney(new BigDecimal(0));
        }
        memberBrokerAccount.setFreezeMoney(memberBrokerAccount.getFreezeMoney().subtract(unfreezeMoney));

        // 增加可用金额
        if (memberBrokerAccount.getAvailableMoney() == null) {
            memberBrokerAccount.setAvailableMoney(new BigDecimal(0));
        }
        BigDecimal availableMoney = memberBrokerAccount.getAvailableMoney().add(unfreezeMoney);
        memberBrokerAccount.setAvailableMoney(availableMoney);
        memberBrokerAccountDao.update(memberBrokerAccount);

        this.saveHistory(memberBrokerAccount, unfreezeMoney, null);
    }

    @WriteTransactional
    public void reduceMoney(String memberId, String brokerAccountId, BigDecimal reduceMoney) {
        MemberBrokerAccountBO memberBrokerAccount = memberBrokerAccountDao.lockBy(memberId, brokerAccountId);
        if (memberBrokerAccount == null) return;

        // 减少可用金额
        if (memberBrokerAccount.getAvailableMoney() == null) {
            memberBrokerAccount.setAvailableMoney(new BigDecimal(0));
        }
        BigDecimal availableMoney = memberBrokerAccount.getAvailableMoney().subtract(reduceMoney);
        memberBrokerAccount.setAvailableMoney(availableMoney);
        memberBrokerAccountDao.update(memberBrokerAccount);

        this.saveHistory(memberBrokerAccount, null, reduceMoney);
    }

    @WriteTransactional
    public void addMoney(String memberId, String brokerAccountId, BigDecimal addMoney, BigDecimal profitMoney) {
        MemberBrokerAccountBO memberBrokerAccount = memberBrokerAccountDao.lockBy(memberId, brokerAccountId);
        if (memberBrokerAccount == null) return;

        // 增加可用金额
        if (memberBrokerAccount.getAvailableMoney() == null) {
            memberBrokerAccount.setAvailableMoney(new BigDecimal(0));
        }
        if (memberBrokerAccount.getProfitMoney() == null) {
            memberBrokerAccount.setProfitMoney(new BigDecimal(0));
        }
        memberBrokerAccount.setAvailableMoney(memberBrokerAccount.getAvailableMoney().add(addMoney));
        memberBrokerAccount.setProfitMoney(memberBrokerAccount.getProfitMoney().add(profitMoney));
        memberBrokerAccountDao.update(memberBrokerAccount);

        this.saveHistory(memberBrokerAccount, null, addMoney);
    }
}
